package com.xci.edu.core.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.github.lvyanyang.annotation.OperateLog;
import com.github.lvyanyang.core.*;
import com.xci.edu.core.dao.EduStudentDao;
import com.xci.edu.core.entity.EduStudent;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.Map;

/**
 * 培训服务
 * @author
 * @since
 */
@Service
public class TrainStudentService  extends BaseService {
    /** 学员基础数据存session key */
    private static final String CurrentStudentSessionKey ="eduStudent";
    /** 学员主键字段 */
    public static final String Student_Id = "id";
    public static final String Student_Cookie_Key = "_student_cookie_";
    /** 学员信息服务 */
    @Resource
    private EduStudentDao eduStudentDao;

    /**
     * 学员登录
     * @param account  账号
     * @param password 密码
     * @param autoLogin 下次是否自动登录
     * @return 登录成功返回true
     */
    public BoolResult<EduStudent> login(@NotBlank(message = "请输入账号") String account, @NotBlank(message = "请输入密码") String password,boolean autoLogin,@NotBlank(message = "请输入验证码") String vcode) {
        var errorMsg = Const.Empty;
        account = account.trim();
        //检测密码强度
        String[] passwords = password.split("");
        if (passwords.length < 6) {
            String msg = "密码输入有误，请确认！";
            return BoolResult.fail(msg);
        }
        //检测账户  验证码
        String loginCode = (String)XCI.getSession().getAttribute("trainLoginCode");
        //大写
        String bigcase = loginCode.toUpperCase();
        //小写
        String lowercase = loginCode.toLowerCase();
        if(!vcode.equals(loginCode) && !vcode.equals(bigcase) && !vcode.equals(lowercase)){
            String msg = "验证码输入有误，请确认！";
            return BoolResult.fail(msg);
        }

        //检测账户（未完成的 !=5）
        EduStudent eduStudent = eduStudentDao.selectEduStudentByIdNumber(account);
        if (eduStudent == null) return BoolResult.fail("账号密码错误");
        if (XCI.isBlank(eduStudent.getPwd()) ) {
            errorMsg = "账号暂时无法登录！";
            //保存日志
            //saveLoginLog(securityUser.getId(), securityUser.getName(), securityUser.getAccount(), 1, false, errorMsg);
            return BoolResult.fail(errorMsg);
        }

        //检测密码(学生密码生成规则 账号，密码，学生姓名简拼)
        String encryptedPwd = XCI.encryptPassword(account,password, eduStudent.getSpell());
        if (!eduStudent.getPwd().equals(encryptedPwd)) {
            errorMsg = "密码输入错误！";
            return BoolResult.fail(errorMsg);
        }
        //检测重复登录
        //账户通过验证
        //region 更新账户登录状态
        //用户登录日志

        //endregion

        //region 登录成功

        //移除账户验证码
        //移除锁定账户信息
        //清除用户权限缓存
        //激活在线用户
        //保存登录成功日志

        //下次是否自动登录
        if (autoLogin) {
            setStudentJwtCookie(eduStudent);
        }

        //endregion

        //保存学员信息到Sesiion
        XCI.getSession().setAttribute(CurrentStudentSessionKey, eduStudent);

        return BoolResult.success(eduStudent);
    }

    /**
     *从Session中获取当前登录学员信息
     */
    public EduStudent getCurrentStudent(){
        return (EduStudent)XCI.getSession().getAttribute(CurrentStudentSessionKey);
    }

    /**
     *从Session中 清除 当前登录学员信息
     */
    public void logout(){
        XCI.getSession().removeAttribute(CurrentStudentSessionKey);
        XCI.removeCookie(Student_Cookie_Key);
    }

    /**
     * 修改学生培训系统密码
     * @param id              用户主键
     * @param currentPassword 当前密码
     * @param newPassword     新密码
     */
    @OperateLog(msg = "修改学生培训系统密码", module = "学员信息", saveParam = false)
    @Transactional(rollbackFor = Exception.class)
    public BoolResult modifyPassword(@NotNull(message = "请指定用户主键") Long id, @NotBlank(message = "请指定当前密码") String currentPassword, @NotBlank(message = "请指定新密码") String newPassword) {
        //验证用户
        EduStudent eduStudent = eduStudentDao.selectById(id);
        if (eduStudent == null) {
            return BoolResult.fail("无效的用户主键");
        }

        if(eduStudent.getStatus() == 0 ){
            return BoolResult.fail("当前学员处于-预报名状态-无法培训");
        }

        if(eduStudent.getStatus() == 1){
            return BoolResult.fail("当前学员处于-报名状态-无法培训");
        }

        //检测密码强度

        //验证当前密码
        String epwd = XCI.encryptPassword(eduStudent.getIdNumber(),currentPassword, eduStudent.getSpell());
        if (!eduStudent.getPwd().equals(epwd)) {
            return BoolResult.fail("当前密码输入不正确,请重新输入");
        }

        //生成新的密钥和密码
        String account = eduStudent.getIdNumber();
        String newPwd = XCI.encryptPassword(account, newPassword, eduStudent.getSpell());
        eduStudentDao.modifyPassword(id,newPwd);
        return BoolResult.success();
    }

    /**
     * 设置学员登录cookie
     */
    public void setStudentJwtCookie(EduStudent eduStudent) {
        var studentId = eduStudent.getId();
        GMap map = GMap.newMap(Student_Id, XCI.encrypt(studentId.toString()));
        Date expireDate = DateUtil.date().offset(DateField.DAY_OF_MONTH, 7);
        String token = XCI.createJwt(map, Const.JWT_SECRET_KEY, expireDate);
        Cookie cookie = new Cookie(Student_Cookie_Key, token);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        //7天
        cookie.setMaxAge(60 * 60 * 24 * 7);
        XCI.setCookie(cookie);
    }

    /**
     * 获取学员登录cookie
     */
    public BoolResult getStudentJwtCookie() {
        String studentToken = XCI.getCookie(Student_Cookie_Key);
        if (studentToken == null) {
            return BoolResult.fail();
        }
        var studentResult = getStudentByToken(studentToken);
        if (studentResult.isSuccess()) {
            BoolResult sresult = onLoginSuccess(studentResult.getData());
            return BoolResult.success();
        }
        return BoolResult.success();
    }

    /**
     * 根据token获取用户对象
     */
    private BoolResult<EduStudent> getStudentByToken(String studentToken) {
        Map<String, Object> map = XCI.parseJwt(studentToken, Const.JWT_SECRET_KEY);
        Object studentIdObj = map.get(Student_Id);
        if (studentIdObj == null || studentIdObj.toString().length() == 0) {
            return BoolResult.fail("非法用户,信息已被篡改");
        }
        String studentId = XCI.decrypt(studentIdObj.toString());
        if (!NumberUtil.isLong(studentId)) {
            return BoolResult.fail("非法用户,信息已被篡改");
        }
        EduStudentService eduStudentService = XCI.getBean(EduStudentService.class);
        EduStudent eduStudent = eduStudentService.selectById(Long.valueOf(studentId));
        if (eduStudent == null) {
            return BoolResult.fail("非法用户,无效的用户标识");
        }
        return BoolResult.success(eduStudent);
    }


    /**
     * 用户登录成功函数
     */
    public BoolResult onLoginSuccess(EduStudent entity) {
        if (entity.getStatus().equals("0")) {
            return BoolResult.fail("当前学员处于预报名状态，无法登录");
        }else if (entity.getStatus().equals("1")) {
            return BoolResult.fail("当前学员处于报名状态，无法登录");
        }else if(entity.getStatus().equals("5")){
            return BoolResult.fail("当前学员处于结业状态，无法登录");
        }
        XCI.getSession().setAttribute(CurrentStudentSessionKey, entity);
        return BoolResult.success();
    }
}
